package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.RelativeDateFormat;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.PageResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.MessageApi;
import com.tanhua.dubbo.api.QuanZiApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.Publish;
import com.tanhua.dubbo.pojo.Visitors;
import com.tanhua.dubbo.vo.QuanZiVo;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.VisitorsVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author Don
 */
@Service
public class QuanZiService {


    @Reference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private PicUploadService picUploadService;

    @Reference
    private VisitorsApi visitorsApi;

    @Autowired
    private UserInfoService userInfoService;

    @Reference(version = "1.0.0")
    private MessageApi messageApi;


    /**
     * 查询好友动态
     * 从请求中获取token page pagesize
     * 校验token 返回user对象
     * 获取用户userId
     * 根据用户userId查询时间线表 quanzi_time_line_userId 返回动态id集合
     * 根据动态id的集合查询动态表 获取所对应的动态信息对象集合(分页查询 page pagesize)
     * 遍历集合 获取发布动态用户的userId 查询用户信息
     * 封装响应对象 并返回
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryPublishList(Integer page, Integer pagesize) {
        // 1.校验token
        User user = UserThreadLocal.get();

        // 2.查询数据
        List<Publish> publishList = quanZiApi.queryPublishList(user.getId(), page, pagesize);

        // 3.封装
        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pagesize);

        ArrayList<QuanZiVo> list = new ArrayList<>();

        for (Publish publish : publishList) {
            Long userId = publish.getUserId();

            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, userId);
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);

            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publish.getId().toString());
            quanZiVo.setUserId(userId);
            quanZiVo.setTextContent(publish.getText());
            quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

            fillUserInfoToQuanZiVo(userInfo, quanZiVo);
            list.add(quanZiVo);
        }
        result.setItems(list);

        return result;
    }

    /**
     * 查询推荐动态
     * 从请求中获取token page pagesize
     * 校验token 返回user对象
     * 获取用户userId
     * 根据用户userId查询redis数据库 返回动态pid字符串 转为long类型pid集合
     * 根据动态pid的集合查询动态表 获取所对应的动态信息对象集合(分页查询 page pagesize)
     * 遍历集合 获取发布动态用户的userId 查询用户信息
     * 封装响应对象 并返回
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryRecommendPublishList(Integer page, Integer pagesize) {
        // 1.校验token
        User user = UserThreadLocal.get();

        // 2.查询数据
        List<Publish> publishList = quanZiApi.queryRecommendPublishList(user.getId(), page, pagesize);

        if (publishList == null) {
            return null;
        }

        //过滤动态是否是已审核状态
        List<Publish> passPublishList = messageApi.filterPublish(publishList);

        // 3.封装
        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pagesize);

        ArrayList<QuanZiVo> list = new ArrayList<>();

        for (Publish publish : passPublishList) {
            Long userId = publish.getUserId();

            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, userId);
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);

            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publish.getId().toString());
            quanZiVo.setUserId(userId);
            quanZiVo.setTextContent(publish.getText());
            quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

            fillUserInfoToQuanZiVo(userInfo, quanZiVo);

/*
            quanZiVo.setAvatar(userInfo.getLogo());
            quanZiVo.setNickname(userInfo.getNickName());
            quanZiVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            quanZiVo.setAge(userInfo.getAge());
            quanZiVo.setTags(userInfo.getTags().split(","));
*/



           /* quanZiVo.setCommentCount(0); //TODO 评论数
            quanZiVo.setDistance("1.2公里"); //TODO 距离
            quanZiVo.setHasLiked(0); //TODO 是否点赞（1是，0否）
            quanZiVo.setLikeCount(0); //TODO 点赞数
            quanZiVo.setHasLoved(0); //TODO 是否喜欢（1是，0否）
            quanZiVo.setLoveCount(0); //TODO 喜欢数*/

            list.add(quanZiVo);
        }
        result.setItems(list);

        return result;
    }

    /**
     * 填充用户信息
     *
     * @param userInfo
     * @param quanZiVo
     */
    private void fillUserInfoToQuanZiVo(UserInfo userInfo, QuanZiVo quanZiVo) {
        BeanUtil.copyProperties(userInfo, quanZiVo, "id");
        quanZiVo.setGender(userInfo.getSex().name().toLowerCase());
        quanZiVo.setTags(StringUtils.split(userInfo.getTags(), ','));

        User user = UserThreadLocal.get();

        quanZiVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount((quanZiVo.getId())))); // 评论数
        quanZiVo.setDistance("1.2公里"); //TODO 距离
        quanZiVo.setHasLiked(quanZiApi.queryUserIsLike(user.getId(), quanZiVo.getId()) ? 1 : 0); // 是否点赞（1是，0否）
        quanZiVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(quanZiVo.getId()))); // 点赞数
        quanZiVo.setHasLoved(quanZiApi.queryUserIsLove(user.getId(), quanZiVo.getId()) ? 1 : 0); // 是否喜欢（1是，0否）
        quanZiVo.setLoveCount(Convert.toInt(quanZiApi.queryLoveCount(quanZiVo.getId()))); // 喜欢数
    }

    /**
     * 发布动态
     *
     * @param textContent   文字动态
     * @param multipartFile 图片动态（支持多张图片)
     * @param location      位置
     * @param longitude     经度
     * @param latitude      纬度
     * @return
     */
    public String savePublish(
            String textContent,
            MultipartFile[] multipartFile,
            String location,
            String longitude,
            String latitude) {
        // 获取当前的登录信息
        User user = UserThreadLocal.get();

        // 封装动态
        Publish publish = new Publish();
        publish.setUserId(user.getId());
        publish.setText(textContent);
        publish.setLocationName(location);
        publish.setLatitude(latitude);
        publish.setLongitude(longitude);
        publish.setSeeType(1);

        // 图片上传
        ArrayList<String> picUrlList = new ArrayList<>();

        for (MultipartFile file : multipartFile) {
            PicUploadResult upload = picUploadService.upload(file);
            // 获取图片路径
            String picUrl = upload.getName();
            picUrlList.add(picUrl);
        }
        // 设置图片地址
        publish.setMedias(picUrlList);

        return quanZiApi.savePublish(publish);
    }

    /**
     * 点赞
     *
     * @param publishId 动态/评论/小视频/视频评论 id
     * @return 点赞数
     */
    public Long likeComment(String publishId) {
        User user = UserThreadLocal.get();
        // 点赞
        Boolean result = quanZiApi.likeComment(user.getId(), publishId);
        if (result) {
            // 查询点赞数
            return quanZiApi.queryLikeCount(publishId);
        }
        return null;
    }

    /**
     * 取消点赞
     *
     * @param publishId 动态/评论/小视频/视频评论 id
     * @return
     */
    public Long disLikeComment(String publishId) {
        User user = UserThreadLocal.get();
        // 取消点赞
        Boolean result = quanZiApi.disLikeComment(user.getId(), publishId);
        if (result) {
            // 查询点赞数
            return quanZiApi.queryLikeCount(publishId);
        }
        return null;
    }

    /**
     * 喜欢
     *
     * @param publishId 动态id
     * @return
     */
    public Long loveComment(String publishId) {
        User user = UserThreadLocal.get();
        Boolean result = quanZiApi.loveComment(user.getId(), publishId);
        if (result) {
            return quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    /**
     * 取消喜欢
     *
     * @param publishId 动态id
     * @return
     */
    public Long disLoveComment(String publishId) {
        User user = UserThreadLocal.get();

        Boolean result = quanZiApi.disLoveComment(user.getId(), publishId);
        if (result) {
            return quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    /**
     * 根据id查询动态
     *
     * @param publishId 动态id
     * @return
     */
    public QuanZiVo queryById(String publishId) {
        User user = UserThreadLocal.get();

        Publish publish = quanZiApi.queryPublishById(publishId);
        if (publish == null) {
            return null;
        }
        // 获取用户id
        Long userId = publish.getUserId();
        // 根据用户id查询用户信息
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getUserId, userId);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);
        // 封装
        QuanZiVo quanZiVo = new QuanZiVo();
        quanZiVo.setId(publish.getId().toString());
        quanZiVo.setUserId(userId);
        quanZiVo.setTextContent(publish.getText());
        quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
        quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

        fillUserInfoToQuanZiVo(userInfo, quanZiVo);
        return quanZiVo;
    }

    /**
     * 查询评论列表
     *
     * @param publishId 评论id
     * @param page      当前页
     * @param pageSize  页尺寸
     * @return
     */
    public PageResult queryCommentsList(String publishId, Integer page, Integer pageSize) {
        User user = UserThreadLocal.get();
        // 查询动态所有评论
        List<Comment> commentList = quanZiApi.queryCommentsList(publishId, page, pageSize);
        // 封装
        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pageSize);

        List<CommentVo> list = new ArrayList<>();
        for (Comment comment : commentList) {
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, comment.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            CommentVo commentVo = new CommentVo();
            commentVo.setId(comment.getId().toHexString());
            commentVo.setAvatar(userInfo.getLogo());
            commentVo.setNickname(userInfo.getNickName());
            commentVo.setContent(comment.getContent());
            commentVo.setCreateDate(DateUtil.format(new Date(comment.getCreated()), "HH:mm"));
            commentVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(commentVo.getId())));
            commentVo.setHasLiked(this.quanZiApi.queryUserIsLike(user.getId(), commentVo.getId()) ? 1 : 0);
            list.add(commentVo);
        }
        result.setItems(list);
        return result;
    }

    /**
     * 发布评论
     *
     * @param publishId 动态/小视频 id
     * @param content   评论文本
     * @return
     */
    public Boolean saveComments(String publishId, String content) {
        User user = UserThreadLocal.get();
        return this.quanZiApi.saveComment(user.getId(), publishId, content);
    }


    public PageResult queryAlbumList(Long userId, Integer page, Integer pageSize) {

        List<Publish> publishList = quanZiApi.queryAlbumList(userId, page, pageSize);

        PageResult result = new PageResult();
        result.setPage(page);
        result.setPagesize(pageSize);

        if (ObjectUtil.isEmpty(publishList)) {
            return result;
        }

        ArrayList<QuanZiVo> list = new ArrayList<>();

        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getUserId, userId);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);

        for (Publish publish : publishList) {

            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publish.getId().toString());
            quanZiVo.setUserId(userId);
            quanZiVo.setTextContent(publish.getText());
            quanZiVo.setImageContent(publish.getMedias().toArray(new String[]{}));
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

            fillUserInfoToQuanZiVo(userInfo, quanZiVo);
            list.add(quanZiVo);
        }
        result.setItems(list);

        return result;
    }

    public List<VisitorsVo> queryVisitors() {
        User user = UserThreadLocal.get();

        List<Visitors> visitorsList = visitorsApi.queryMyVisitor(user.getId());

        if (CollUtil.isEmpty(visitorsList)) {
            return Collections.emptyList();
        }
        List<VisitorsVo> list = new ArrayList<>();

        for (Visitors visitors : visitorsList) {
            VisitorsVo visitorsVo = new VisitorsVo();

            UserInfo userInfo = userInfoService.queryUserInfoByUserId(visitors.getVisitorUserId());

            visitorsVo.setId(userInfo.getUserId());
            visitorsVo.setAvatar(userInfo.getLogo());
            visitorsVo.setAge(userInfo.getAge());
            visitorsVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            visitorsVo.setNickname(userInfo.getNickName());
            visitorsVo.setTags(userInfo.getTags().split(","));
            visitorsVo.setFateValue(visitors.getScore().intValue());

            list.add(visitorsVo);
        }
        return list;
    }
}
